package com.example.expinterview.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.expinterview.dto.IntegralDto;
import com.example.expinterview.dto.PageDto;
import com.example.expinterview.dto.SearchDto;
import com.example.expinterview.entity.*;
import com.example.expinterview.entity.enums.EiUserIntegralUseEnum;
import com.example.expinterview.entity.enums.ErrorCodeEnum;
import com.example.expinterview.mapper.EiArticleMapper;
import com.example.expinterview.mapper.EiRecordMapper;
import com.example.expinterview.mapper.EiShareArticleLogMapper;
import com.example.expinterview.mapper.EiUserIntegralValueConfigMapper;
import com.example.expinterview.service.IEiArticleService;
import com.example.expinterview.service.IEiListService;
import com.example.expinterview.service.IEiUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

/**
 * @classname: EiArticleServiceImpl
 * @description: TODO
 * @author: kaiser
 * @date: 2021/10/18 21:58
 * @version: 1.0
 */
@Service
public class EiArticleServiceImpl extends ServiceImpl<EiArticleMapper, EiArticle> implements IEiArticleService {

    private final EiRecordMapper mapper;
    @Autowired
    private IEiUserService eiUserService;
    @Autowired
    private EiUserIntegralValueConfigMapper eiUserIntegralValueConfigMapper;
    @Autowired
    private EiShareArticleLogMapper eiShareArticleLogMapper;
    @Autowired
    private IEiListService eiListService;

    @Autowired
    public EiArticleServiceImpl(EiRecordMapper mapper) {
        this.mapper = mapper;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean publishArticle(EiArticle article) {

        boolean b = saveOrUpdate(article);
        EiUserIntegralValueConfig eiUserIntegralValueConfig = eiUserIntegralValueConfigMapper.selectOne(
                Wrappers.<EiUserIntegralValueConfig>lambdaQuery()
                        .eq(EiUserIntegralValueConfig::getIntegralUseId, EiUserIntegralUseEnum.PUBLISH_ARTICLE.getValue())
        );
        //增加积分
        IntegralDto integralDto = new IntegralDto();
        integralDto.setArticleId(article.getId());
        integralDto.setReason("发布面经");
        integralDto.setType(true);
        integralDto.setUserId(article.getUserId());
        integralDto.setValue(Math.abs(eiUserIntegralValueConfig.getValue()));
        ResultBody resultBody = eiListService.create(integralDto);
        if (!resultBody.isSuccess()) {
            throw new RuntimeException("创建积分明细失败,this param is "+ integralDto.toString() +", this result is "+resultBody.toString());
        }
        return b;
    }

    @Override
    public ResultBody selectPageList(PageDto page) {
        Page<EiArticle> iPage = new Page<>(page.getPage(), page.getSize());
        QueryWrapper<EiArticle> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("gmt_create");
        if (Objects.isNull(page.getType())) {
            wrapper.isNotNull("id");
        } else {
            wrapper.isNotNull("id").eq("type", page.getType());
        }
        Page<EiArticle> selectPage = baseMapper.selectPage(iPage, wrapper);
        HashMap<String, Object> map = new HashMap<>(5);
        map.put("total", selectPage.getTotal());
        map.put("page", selectPage.getCurrent());
        map.put("size", selectPage.getSize());
        map.put("list", selectPage.getRecords());
        map.put("pageTotal", selectPage.getPages());
        return ResultBody.success(map);
    }

    @Override
    public ResultBody searchList(SearchDto value) {
        String val = "%" + value.getSearchValue() + "%";
        List<EiArticle> list = baseMapper.selectList(new QueryWrapper<EiArticle>()
                .like("title", val).or()
                .like("user_name", val)
                .orderByDesc("gmt_create"));
            EiRecord record = new EiRecord();
            record.setUserId(value.getId());
            record.setSearchValue(value.getSearchValue());
            record.setMatchNumber(list.size());
            mapper.insert(record);
        return ResultBody.list(list);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultBody<EiArticle> getDetailById(Long articleId, Long userId,String shareNo) {
        //todo 消耗面经 如果积分不够提示去分享或者发布获得积分
        // todo 分享过来查看面经 如果是自己点自己不增加积分，新用户与老用户增加的积分不一样
        /**
         * 1. 查询当前用户积分
         * 2. 积分不够提示返回
         * 3. 分享查看-按规则增加积分
         * 4. 减积分-1
         */
        EiUser eiUser = eiUserService.getById(userId);
        if (Objects.isNull(eiUser)) {
            return ResultBody.fail();
        }

        // 查看自己发布的不需要积分
        EiArticle article = getById(articleId);
        if (Objects.isNull(article)) {
            return ResultBody.fail();
        }

        if (article.getUserId().equals(userId)) {
            return ResultBody.success(article);
        }

        // 获取查看积分值
        List<EiUserIntegralValueConfig> eiUserIntegralValueConfigs = eiUserIntegralValueConfigMapper.selectList(
                Wrappers.<EiUserIntegralValueConfig>lambdaQuery()
                        .in(EiUserIntegralValueConfig::getIntegralUseId,
                                EiUserIntegralUseEnum.GET_ARTICLE.getValue(),
                                EiUserIntegralUseEnum.SHARE_ARTICLE.getValue())
                .orderByAsc(EiUserIntegralValueConfig::getIntegralUseId)
        );

        EiUserIntegralValueConfig eiUserIntegralValueConfig_getArticle = eiUserIntegralValueConfigs.get(0);

        EiUserIntegralValueConfig eiUserIntegralValueConfig_shareArticle = eiUserIntegralValueConfigs.get(1);
        // 剩余积分
        int i = eiUser.getIntegral() - eiUserIntegralValueConfig_getArticle.getValue();
        if (i < 0) {
            return ResultBody.fail(ErrorCodeEnum.FAIL.getCode(),"积分不够了，去分享面经或者发布面经获得积分吧");
        }

        // 减少积分
        IntegralDto integralDto = new IntegralDto();
        integralDto.setArticleId(articleId);
        integralDto.setReason("查看面经: "+ article.getTitle());
        integralDto.setType(false);
        integralDto.setUserId(userId);
        integralDto.setValue(Math.abs(eiUserIntegralValueConfig_getArticle.getValue()));
        ResultBody resultBody = eiListService.create(integralDto);
        if (!resultBody.isSuccess()) {
            throw new RuntimeException("查看面经减少积分失败,this param is "+ integralDto.toString() +", this result is "+resultBody.toString());
        }

        if (StringUtils.isNotEmpty(shareNo)) {
            //  分享查看
            EiShareArticleLog eiShareArticleLog = eiShareArticleLogMapper.selectOne(
                    Wrappers.<EiShareArticleLog>lambdaQuery()
                            .eq(EiShareArticleLog::getShareNo, shareNo)
            );

            if (Objects.nonNull(eiShareArticleLog)) {
                if (!eiShareArticleLog.getUserId().equals(userId)) {
                    // todo 区分老用户和新用户
                    // 增加积分
                    integralDto = new IntegralDto();
                    integralDto.setArticleId(articleId);
                    integralDto.setReason("分享面经");
                    integralDto.setType(true);
                    integralDto.setUserId(eiShareArticleLog.getUserId());
                    integralDto.setValue(Math.abs(eiUserIntegralValueConfig_shareArticle.getValue()));
                    resultBody = eiListService.create(integralDto);
                    if (!resultBody.isSuccess()) {
                        throw new RuntimeException("分享面经增加积分明细失败,this param is "+ integralDto.toString() +", this result is "+resultBody.toString());
                    }
                }
            }
        }
        return ResultBody.success(article);
    }

    @Override
    public String saveShareArticleLog(Long articleId, Long userId) {
        EiShareArticleLog eiShareArticleLog = new EiShareArticleLog();
        eiShareArticleLog.setUserId(userId);
        eiShareArticleLog.setArticleId(articleId);
        eiShareArticleLog.setShareNo(UUID.randomUUID().toString());
        int insert = eiShareArticleLogMapper.insert(eiShareArticleLog);
        return eiShareArticleLog.getShareNo();
    }
}
